package org.summerframework.component.upload.converter;

import org.summerframework.component.upload.FileUploadService;
import org.summerframework.component.upload.file.service.dto.FileUserRelDTO;
import org.summerframework.component.upload.type.FileUploadDTO;
import org.summerframework.core.annotation.MultipartFileFormat;
import org.summerframework.core.util.Base64Util;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashSet;
import java.util.Set;

/**
 * @author 石超
 * @version v1.0.0
 */
public class MultipartFileConverter implements ConditionalGenericConverter {

    private FileUploadService fileUploadService;

    public MultipartFileConverter(FileUploadService fileUploadService) {
        this.fileUploadService = fileUploadService;
    }

    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        Set<ConvertiblePair> set = new HashSet<>();
        set.add(new ConvertiblePair(MultipartFile.class, Long.class));
        set.add(new ConvertiblePair(MultipartFile.class, String.class));
        set.add(new ConvertiblePair(MultipartFile.class, FileUserRelDTO.class));
        set.add(new ConvertiblePair(String.class, Long.class));
        set.add(new ConvertiblePair(String.class, String.class));
        set.add(new ConvertiblePair(String.class, FileUserRelDTO.class));
        return set;
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        if (source == null) {
            return null;
        }
        MultipartFileFormat annotation = targetType.getAnnotation(MultipartFileFormat.class);
        FileUserRelDTO fileUserRelDTO = null;

        if (MultipartFile.class.isAssignableFrom(sourceType.getObjectType())) {
            MultipartFile multipartFile = (MultipartFile) source;
            fileUserRelDTO = fileUploadService.uploadFile(FileUploadDTO.file(multipartFile));
        } else if (String.class.isAssignableFrom(sourceType.getObjectType())) {
            String base64 = (String) source;
            int i;

            if ((i = base64.indexOf(";base64,")) > -1) {
                base64 = base64.substring(i + 8);
            }

            fileUserRelDTO = fileUploadService.uploadFile(FileUploadDTO.file(Base64Util.decodeAsByte(base64), annotation.fileName()));
        }

        if (fileUserRelDTO == null) {
            return null;
        } else if (Long.class.isAssignableFrom(targetType.getObjectType())) {
            return fileUserRelDTO.getId();
        } else if (String.class.isAssignableFrom(targetType.getObjectType())) {
            return fileUserRelDTO.getUrl();
        } else if (FileUserRelDTO.class.isAssignableFrom(targetType.getObjectType())) {
            return fileUserRelDTO;
        } else {
            return null;
        }
    }

    @Override
    public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
        return targetType.hasAnnotation(MultipartFileFormat.class);
    }
}
